//湖南跑得快算法
module.exports = function() {
  var CARD_TYPE_SIGN          = 1   //单牌
  var CARD_TYPE_PAIRS         = 2   //对子
  var CARD_TYPE_EVENFOR_PAIRS     = 3   //连对
  var CARD_TYPE_STRAIGHT        = 4   //顺子  任意5张或者5张以上点数相连的牌。10JQKA最大,2不能放入顺子
  var CARD_TYPE_THREE         = 5   //三张
  var CARD_TYPE_THREE_WITH_ONE    = 6     //三带一
  var CARD_TYPE_THREE_WITH_TWO    = 7     //三带二
  var CARD_TYPE_PLANE         = 8   //飞机  两对或以上点数相连的三带二
  var CARD_TYPE_FOUR_WITH_THREE     = 9  //四带三  四带三不算炸弹
  var CARD_TYPE_BOMB          = 10   //炸弹
  var CARD_TYPE_SANSHUN       = 11   //三顺
  var card_weight = [0,14,20,3,4,5,6,7,8,9,10,11,12,13]
  this.cards = []       //初始牌库
  this.playerHandler = []   //玩家手牌
  this.playerNum = 3      //玩家人数
  /**
   * 洗牌
   * @Author   wfd
   * @DateTime 2018-05-14
   */
  this.shuffle = function() {
    this.cards = []
    this.playerHandler = []
    this.cards.push({num : 2,type : 3})
    this.cards.push({num : 1,type : 0})
    this.cards.push({num : 1,type : 1})
    this.cards.push({num : 1,type : 2})
    for(var i = 3;i <= 13;i++){
      for(var j = 0;j < 4;j++){
        this.cards.push({num : i,type : j})
      }
    }
    //洗牌
    for(var i = 0;i < this.cards.length;i++){
      var tmpIndex = Math.floor(Math.random() * this.cards.length)
      var tmpCard = this.cards[i]
      this.cards[i] = this.cards[tmpIndex]
      this.cards[tmpIndex] = tmpCard
    }
  }
  /**
   * 发牌
   * @Author   wfd
   * @DateTime 2018-05-14
   */
  this.sendCard = function(keyCard,luckys,minCardValue) {
    var controlFlag = false
    for(var i = 0;i < 3;i++){
      if(luckys && luckys[i] && typeof(luckys[i]) == "number"){
        controlFlag = true
      }
    }
    if(controlFlag){
      luckysMap = [0,1,2]
      // console.log("luckys11111")
      // console.log(luckys)
      for(var i = 0;i < luckys.length - 1;i++){
        for(var j = i + 1;j < luckys.length;j++){
          if(luckys[j] > luckys[i]){
            var tmpLucky = luckys[j]
            luckys[j] = luckys[i]
            luckys[i] = tmpLucky
            var tmpIndex = luckysMap[j]
            luckysMap[j] = luckysMap[i]
            luckysMap[i] = tmpIndex
          }
        }
      }
      console.log("luckys22222")
      console.log(luckys)
      console.log(luckysMap)
    }
    var count = 0
    var maxValue = 0
    while(count < 1000){
      count++
      this.shuffle()
      for(var i = 0;i < this.playerNum;i++){
        this.playerHandler[i] = this.cards.splice(0,16)
        for(var j = 0;j < this.playerHandler[i].length;j++){
          this.playerHandler[i][j].state = true
          this.playerHandler[i][j].index = j
        }
      }
      var valueList = []
      for(var i = 0;i < this.playerNum;i++){
        valueList[i] = {index : i,value : this.getHandCardValue(this.playerHandler[i]),data : this.playerHandler[i]}
        // valueList[i] = {index : i,data : this.playerHandler[i]}
      }
      //拥有关键牌
      var keyIndex = this.getCardVest(keyCard)
      if(keyIndex !== false){
        valueList[keyIndex].value += 25
      }
      //排序
      valueList.sort(function(a,b) {return b.value - a.value})
      // console.log(valueList)
      if(controlFlag){
        if(valueList[0].value - valueList[2].value >= luckys[0] - luckys[2] 
          && valueList[0].value - valueList[1].value >= luckys[0] - luckys[1]
          && valueList[1].value - valueList[2].value >= luckys[1] - luckys[2]
          && valueList[2].value >= minCardValue
          ){
          for(var i = 0;i < valueList.length;i++){
            this.playerHandler[luckysMap[i]] = valueList[i].data
          }
          break
        }
        var tmpValue = valueList[0].value - valueList[2].value
        if(tmpValue > maxValue){
          maxValue = tmpValue
          console.log("maxValue :",maxValue)
          for(var i = 0;i < valueList.length;i++){
            this.playerHandler[luckysMap[i]] = valueList[i].data
          }
        }
      }else{
        if(valueList[2].value >= minCardValue){
          break
        }
      }
    }
    console.log("sendFinish : "+count)
    for(var i = 0;i < 3;i++){
      console.log(this.playerHandler[i])
      console.log(this.getHandCardValue(this.playerHandler[i]))
    }
  }
  /**
   * 获取牌型
   * @Author   wfd
   * @DateTime 2018-05-14
   * @param    {[arr]}   cardList      [牌数组]
   * @return   {[card]}                [牌型]
   */
  this.getCardType = function(cardList,handRest) {
    if(!cardList || !cardList.length){
      return
    }
    //排序
    for(var i = 0;i < cardList.length - 1;i++){
      for(var j = i + 1;j < cardList.length;j++){
        if(card_weight[cardList[j].num] > card_weight[cardList[i].num] || (cardList[j].num == cardList[i].num && cardList[j].type > cardList[i].type)){
          var tmp = cardList[j]
          cardList[j] = cardList[i]
          cardList[i] = tmp
        }
      }
    }
    var result = {
      type : 0,
      maxCard : {},
      cardList : cardList
    }

    //炸弹
    if(cardList.length == 4){
      if(cardList[0].num == cardList[1].num && cardList[1].num == cardList[2].num && cardList[2].num == cardList[3].num){
        result.type = CARD_TYPE_BOMB
        result.maxCard = cardList[0]
        return result
      }
    }
    //统计每个数字数量
    var cardNumList = {}
    for(var i = 0;i < cardList.length;i++){
      if(!cardNumList[cardList[i].num]){
        cardNumList[cardList[i].num] = 0
      }
      cardNumList[cardList[i].num]++
    }
    //飞机  两对或以上点数相连的三带二
    if(cardList.length % 5 == 0 && cardList.length >= 10){
      var threeList = []
      for(var i in cardNumList){
        if(cardNumList[i] == 3){
          threeList.push(parseInt(i))
        }
      }
      //排序
      for(var i = 0;i < threeList.length - 1;i++){
        for(var j = i + 1;j < threeList.length;j++){
          if(card_weight[threeList[j]] > card_weight[threeList[i]]){
            var tmp = threeList[j]
            threeList[j] = threeList[i]
            threeList[i] = tmp
          }
        }
      }
      var a_list = []
      var b_list = []
      //找出连续三张
      for(var i = 0;i < threeList.length;i++){
        //正计算出最长
        if(a_list.length === 0 || card_weight[threeList[i]] === (card_weight[a_list[a_list.length - 1]] - 1)){
          a_list.push(threeList[i])
        }
      }
      for(var i = threeList.length - 1;i >= 0;i--){
        //反计算出最长
        if(b_list.length === 0 || card_weight[threeList[i]] === (card_weight[b_list[b_list.length - 1]] + 1)){
          b_list.push(threeList[i])
        }
      }
      if(a_list.length >= b_list.length){
        threeList = a_list
      }else{
        threeList = b_list
      }
      if(cardList.length == threeList.length * 5){
        for(var i = 0;i < cardList.length;i++){
          for(var j = 0;j < threeList.length;j++){
            if(cardList[i].num == threeList[j]){
              result.type = CARD_TYPE_PLANE
              result.maxCard = cardList[i]
              return result
            }
          }
        }
      }
    }
    //三顺
    if(cardList.length % 3 == 0 && cardList.length >= 6){
      var threeList = []
      for(var i in cardNumList){
        if(cardNumList[i] == 3){
          threeList.push(parseInt(i))
        }
      }
      //排序
      for(var i = 0;i < threeList.length - 1;i++){
        for(var j = i + 1;j < threeList.length;j++){
          if(card_weight[threeList[j]] > card_weight[threeList[i]]){
            var tmp = threeList[j]
            threeList[j] = threeList[i]
            threeList[i] = tmp
          }
        }
      }
      if(threeList.length * 3 === cardList.length){
        var flag = true
        for(var i = 1;i < threeList.length;i++){
          if(card_weight[threeList[i]] !== (card_weight[threeList[i - 1]] - 1)){
            flag = false
          }
        }
        if(flag){
            result.type = CARD_TYPE_SANSHUN
            result.maxCard = cardList[0]
            return result
        }
      }
    }
    //四带三
    if(cardList.length == 7){
      for(var i = 0;i < cardList.length;i++){
        if(cardNumList[cardList[i].num] == 4){
          result.type = CARD_TYPE_FOUR_WITH_THREE
          result.maxCard = cardList[i]
          return result
        }
      }
    }
    //三带二
    if(cardList.length == 5){
      for(var i = 0;i < cardList.length;i++){
        if(cardNumList[cardList[i].num] == 3){
          result.type = CARD_TYPE_THREE_WITH_TWO
          result.maxCard = cardList[i]
          return result
        }
      }
    }
    //手牌剩余数量
    if(handRest < 5 && cardList.length < 5){
      //三带一
      if(cardList.length == 4){
        for(var i = 0;i < cardList.length;i++){
          if(cardNumList[cardList[i].num] == 3){
            result.type = CARD_TYPE_THREE_WITH_ONE
            result.maxCard = cardList[i]
            return result
          }
        }
      }
      //三张
      if(cardList.length == 3){
        if(cardList[0].num == cardList[1].num && cardList[1].num == cardList[2].num){
          result.type = CARD_TYPE_THREE
          result.maxCard = cardList[0]
          return result
        }
      }
    }
    //顺子
    if(cardList.length >= 5){
      var straightFlag = true
      for(var i = 0;i < cardList.length - 1;i++){
        if(card_weight[cardList[i].num] !== card_weight[cardList[i + 1].num] + 1){
          straightFlag = false
          break
        }
      }
      if(straightFlag){
        result.type = CARD_TYPE_STRAIGHT
        result.maxCard = cardList[0]
        return result
      }
    }
    //连对
    if(cardList.length % 2 == 0 && cardList.length > 2){
      var lianduiFlag = true
      for(var i = 0;i < cardList.length - 2;i += 2){
        if(card_weight[cardList[i].num] != card_weight[cardList[i+1].num] || card_weight[cardList[i].num] != card_weight[cardList[i+2].num] + 1){
          lianduiFlag = false
          break
        }
      }
      if(lianduiFlag){
        result.type = CARD_TYPE_EVENFOR_PAIRS
        result.maxCard = cardList[0]
        return result
      }
    }
    //对子
    if(cardList.length == 2 && cardList[0].num == cardList[1].num){
      result.type = CARD_TYPE_PAIRS
      result.maxCard = cardList[0]
      return result
    }
    //单牌
    if(cardList.length == 1){
      result.type = CARD_TYPE_SIGN
      result.maxCard = cardList[0]
      return result
    }
    return result
  }
  /**
   * 获取某张牌归属
   * @Author   wfd
   * @DateTime 2018-05-14
   * @param    {[card]}   card    [牌]
   * @return   {[chair]}          [所属椅子]
   */
  this.getCardVest = function(card) {
    if(!card){
      return false
    }
    for(var i = 0;i < this.playerNum;i++){
      for(var j = 0;j < this.playerHandler[i].length;j++){
        if(this.playerHandler[i][j].num == card.num && this.playerHandler[i][j].type == card.type){
          return i
        }
      }
    }
    return false
  }
  /**
   * 牌型比较
   * @Author   wfd
   * @DateTime 2018-05-14
   * @param    {[type]}   result1 [牌型1]
   * @param    {[type]}   result2 [牌型2]
   * @return   {[type]}           [牌型2赢过牌型1时返回true，否则false]
   */
  this.compare = function(result1,result2) {
    //只有炸弹能打其他牌型
    if(result2.type != result1.type && result2.type !== CARD_TYPE_BOMB){
      return false
    }
    //炸弹可以打任何牌型
    if(result2.type == CARD_TYPE_BOMB && result1.type !== CARD_TYPE_BOMB){
      return true
    }
    //同牌型比较maxCard大小
    if(card_weight[result2.maxCard.num] > card_weight[result1.maxCard.num]){
      if(result2.type == CARD_TYPE_BOMB){
        //若是炸弹则可以打任何牌型
        return true
      }else{
        //其他牌型需要一样的牌数量
        if(result1.cardList.length == result2.cardList.length){
          return true
        }else{
          return false
        }
      }
    }else{
      return false
    }
  }
  /**
   * 牌型比较
   * @Author   wfd
   * @DateTime 2018-05-14
   * @param    {[type]}   result1 [牌型1]
   * @param    {[type]}   result2 [牌型2]
   * @return   {[type]}           [牌型2赢过牌型1时返回true，否则false]
   */
  this.compareWithType = function(result1,result2) {
    //只有炸弹能打其他牌型
    if(result2.type != result1.type && result2.type !== CARD_TYPE_BOMB){
      return false
    }
    //炸弹可以打任何牌型
    if(result2.type == CARD_TYPE_BOMB && result1.type !== CARD_TYPE_BOMB){
      return true
    }
    //同牌型比较maxCard大小
    if(card_weight[result2.maxCard.num] > card_weight[result1.maxCard.num] || 
      (card_weight[result2.maxCard.num] === card_weight[result1.maxCard.num] && result2.maxCard.type > result1.maxCard.type)){
      if(result2.type == CARD_TYPE_BOMB){
        //若是炸弹则可以打任何牌型
        return true
      }else{
        //其他牌型需要一样的牌数量
        if(result1.cardList.length == result2.cardList.length){
          return true
        }else{
          return false
        }
      }
    }else{
      return false
    }
  }
  /**
   * 比较两张牌大小
   * @Author   wfd
   * @DateTime 2018-05-16
   * @param    {[type]}   card1 [第一张牌]
   * @param    {[type]}   card2 [第二张牌]
   * @return   {[type]}         [第一张牌大时返回true，否则为false]
   */
  this.compareType = function(card1,card2) {
    if(card_weight[card1.num] > card_weight[card2.num] || (card1.num == card2.num && card1.type > card2.type)){
      return true
    }else{
      return false
    }
  }
  /**
   * 获取最佳分区算法
   * @Author   wfd
   * @DateTime 2018-05-14
   * @param    {[type]}   handCard [手牌]
   * @return   {[type]}            [description]
   */
  this.getBestSubarea = function(handCard) {
    var bestSubarea = []
    var cardList = []
    var numMap = {}
    var threeArea = []
    var pairsArea = []
    var signArea = []

    var numList = {}
    var handRest = 0
    for(var i = 0;i < handCard.length;i++){
      if(handCard[i].state){
        handRest++
        cardList.push(handCard[i])
        if(!numList[handCard[i].num]){
          numList[handCard[i].num] = 0
        }
        numList[handCard[i].num]++
        numMap[handCard[i].index] = handCard[i].num
      }
    }
    //排序
    for(var i = 0;i < cardList.length - 1;i++){
      for(var j = i + 1;j < cardList.length;j++){
        if(card_weight[cardList[j].num] > card_weight[cardList[i].num] || (cardList[j].num == cardList[i].num && cardList[j].type > cardList[i].type)){
          var tmp = cardList[j]
          cardList[j] = cardList[i]
          cardList[i] = tmp
        }
      }
    }
    // console.log("cardList")
    // console.log(cardList)
    //存入炸弹
    for(var i in numList){
      if(numList[i] == 4){
        var tmpArea = []
        for(var j = 0;j < cardList.length;j++){
          if(cardList[j].num == i){
            tmpArea.push(cardList[j])
          }
        }
        bestSubarea.push(tmpArea)
      }
    }
    //初始区分
    for(var i = 0;i < cardList.length;i++){
      if(numList[cardList[i].num] == 4){
        cardList[i].belong = CARD_TYPE_BOMB
      }else if(numList[cardList[i].num] == 3){
        cardList[i].belong = CARD_TYPE_THREE
      }else{
        cardList[i].belong = CARD_TYPE_SIGN
      }
    }
    for(var i in numList){
      if(numList[i] == 4){
        delete numList[i]
      }else if(numList[i] == 3){
        threeArea.push(parseInt(i))
        delete numList[i]
      }
    }
    var numArr = []
    for(var i in numList){
      numArr.push(parseInt(i))
    }
    numArr.sort(function(a,b){return card_weight[a] - card_weight[b]})
    //先判断顺子组合
    var result1 = this.getBestStraight(numArr,numList)
    //再判断连对组合
    var result2 = this.getBestPairs(numArr,numList)
    if(result1.minSign <= result2.minSign){
      //使用顺子组合
      for(var i = 0;i < result1.bestStraight.length;i++){
        var tmpArea = []
        for(var j = 0;j < result1.bestStraight[i].length;j++){
          for(var k = 0;k < cardList.length;k++){
            if(cardList[k].belong == CARD_TYPE_SIGN && cardList[k].num == result1.bestStraight[i][j]){
              cardList[k].belong = CARD_TYPE_STRAIGHT
              tmpArea.push(cardList[k])
              break
            }
          }
        }
        bestSubarea.push(tmpArea)
      }
    }else{
      //使用对子组合
      for(var i = 0;i < result2.bestStraight.length;i++){
        var tmpArea = []
        for(var j = 0;j < result2.bestStraight[i].length;j++){
          for(var k = 0;k < cardList.length;k++){
            var count = 0
            if(cardList[k].belong == CARD_TYPE_SIGN && cardList[k].num == result2.bestStraight[i][j]){
              cardList[k].belong = CARD_TYPE_EVENFOR_PAIRS
              count++
              tmpArea.push(cardList[k])
              if(count == 2){
                break
              }
            }
          }
        }
        bestSubarea.push(tmpArea)
      }
    }
    //判断对子
    numList = {}

    for(var i = 0;i < cardList.length;i++){
      if(cardList[i].belong == CARD_TYPE_SIGN){
        if(!numList[cardList[i].num]){
          numList[cardList[i].num] = 0
        }
        numList[cardList[i].num]++
      }
    }
    for(var i in numList){
      if(numList[i] == 2){
        var tmpArea = []
        for(var k = 0;k < cardList.length;k++){
          var count = 0
          if(cardList[k].belong == CARD_TYPE_SIGN && cardList[k].num == i){
            cardList[k].belong = CARD_TYPE_PAIRS
            count++
            tmpArea.push(cardList[k])
            if(count == 2){
              break
            }
          }
        }
        pairsArea.push(tmpArea)
      }else{
        var tmpArea = []
        for(var k = 0;k < cardList.length;k++){
          if(cardList[k].belong == CARD_TYPE_SIGN && cardList[k].num == i){
            cardList[k].belong = CARD_TYPE_SIGN
            tmpArea.push(cardList[k])
            break
          }
        }
        signArea.push(tmpArea)
      }
    }
    //排序
    signArea.sort(function(a,b){return card_weight[a[0].num] > card_weight[b[0].num] || (a[0].num == b[0].num && a[0].type > b[0].type)})
    pairsArea.sort(function(a,b){return card_weight[a[0].num] > card_weight[b[0].num] || (a[0].num == b[0].num && a[0].type > b[0].type)})
    //判断三条组合
    if(threeArea.length > 0){
      if(cardList.length <= 5){
        //剩余牌不足五张时可打三带一 三张
        var tmpArea = []
        for(var k = 0;k < cardList.length;k++){
          tmpArea.push(cardList[k])
        }
        bestSubarea.push(tmpArea)
        signArea = []
        pairsArea = []
      }else{
        //排序
        threeArea.sort(function(a,b){return card_weight[a] - card_weight[b]})
        var tmpArr = this.getContinuousArray(threeArea)
        while(tmpArr.length){
          var numList = tmpArr.shift()
          var tmpAllArea = []
          for(var i = 0;i < numList.length;i++){
            var tmpArea = this.getCardIndex(cardList,numList[i],3)
            if(signArea.length >= 2 && card_weight[signArea[0][0].num] < 14 && card_weight[signArea[1][0].num] < 14){
              tmpArea.push(signArea.shift()[0])
              tmpArea.push(signArea.shift()[0])
              tmpAllArea = tmpAllArea.concat(tmpArea)
            }else if(pairsArea.length >= 1 && card_weight[pairsArea[0][0].num] < 14){
              tmpArea = tmpArea.concat(pairsArea.shift())
              tmpAllArea = tmpAllArea.concat(tmpArea)
            }else{
              for(var j = i + 1; j < numList.length;j++){
                tmpArea = tmpArea.concat(this.getCardIndex(cardList,numList[j],3))
              }
              bestSubarea.push(tmpArea)
              break
            }
          }
          if(tmpAllArea.length){
            bestSubarea.push(tmpAllArea)
          }
        }
      }
    }
    //存入连对或对子
    var tmpArea = []
    for(var i = 0;i < pairsArea.length;i++){
      tmpArea = tmpArea.concat(pairsArea[i])
      // console.log(i,pairsArea[i],tmpArea)
      if(i == pairsArea.length - 1 || (card_weight[pairsArea[i][0].num + 1] != card_weight[pairsArea[i+1][0].num])){
        bestSubarea.push(tmpArea)
        tmpArea = []
      }
    }
    // console.log(pairsArea)
    // for(var i = 0;i < pairsArea.length;i++){
    //   bestSubarea.push(pairsArea[i])
    // }
    for(var i = 0;i < signArea.length;i++){
      bestSubarea.push(signArea[i])
    }
    return bestSubarea
  }
  /**
   * 获取连对组合
   * @Author   wfd
   * @DateTime 2018-05-15
   * @param    {[type]}   arr  [原始数组]
   * @param {[type]}    list [数字数量]
   * @return   {[type]}        [description]
   */
  this.getBestPairs = function(arr,list) {
    var new_arr = []
    for(var i = 0;i < arr.length;i++){
      if(list[arr[i]] >= 2){
        new_arr.push(arr[i])
      }
    }
    var numList = {}
    for(var i in list){
      numList[i] = list[i]
    }
    var tmpStraight = []
    var arrResult = this.getContinuousArray(new_arr)
    for(var i = 0;i < arrResult.length;i++){
      if(arrResult[i].length >= 2){
        tmpStraight.push(arrResult[i])
        for(var j = 0;j < arrResult[i].length;j++){
          numList[arrResult[i][j]] -= 2
        }
      }
    }
    var signCount = 0
    for(var i in numList){
      if(numList[i] == 1){
        signCount++
      }
    }
    var result = {
      minSign : signCount,
      bestStraight : tmpStraight
    }
    // console.log(result)
    return result
  }
  /**
   * 获取最佳顺子组合
   * @Author   wfd
   * @DateTime 2018-05-15
   * @param    {[type]}   arr  [原始数组]
   * @param {[type]}    list [数字数量]
   * @return   {[type]}        [description]
   */
  this.getBestStraight = function(arr,list) {
    var new_arr = []
    for(var i = 0;i < arr.length;i++){
      new_arr.push(arr[i])
    }
    var shunArea = []
    var bestStraight = []
    var minSign = new_arr.length
    var minAll = new_arr.length
    //正序算
    for(var z = 0;z <= new_arr.length - 5;z++){
      // console.log("==================z========================= : "+z)
      var numList = {}
      for(var i in list){
        numList[i] = list[i]
      }
      var tmpStraight = []
      //指定位置开始获取
      var arrResult = this.getContinuousArray(new_arr.slice(z,new_arr.length))
      // console.log("arrResult11")
      // console.log(arrResult)
      //获取其中长度大于5的取出
      for(var i = 0;i < arrResult.length;i++){
        if(arrResult[i].length >= 5){
          tmpStraight.push(arrResult[i])
          for(var j = 0;j < arrResult[i].length;j++){
            numList[arrResult[i][j]]--
          }
        }
      }
      var numArr = []
      for(var i in numList){
        if(numList[i] > 0){
          numArr.push(parseInt(i))
        }
      }
      numArr.sort(function(a,b){return card_weight[a] - card_weight[b]})
      // console.log("numArr : ")
      // console.log(numArr)
      //所有数字再次获取
      arrResult = this.getContinuousArray(numArr.slice(0,numArr.length))
      // console.log("arrResult22")
      // console.log(arrResult)
      //获取其中长度大于5的取出
      for(var i = 0;i < arrResult.length;i++){
        if(arrResult[i].length >= 5){
          tmpStraight.push(arrResult[i])
          for(var j = 0;j < arrResult[i].length;j++){
            numList[arrResult[i][j]]--
          }
        }
      }
      // console.log("numList : ")
      // console.log(numList)
      var signCount = 0
      var allCount = 0
      for(var i in numList){
        if(numList[i] == 1){
          signCount++
        }
        allCount += numList[i]
      }
      if(minSign == false){
        minSign = signCount
        minAll = allCount
        bestStraight = tmpStraight
      }else{
        if(minSign > signCount || (minSign == signCount && allCount > minAll)){
          minSign = signCount
          minAll = allCount
          bestStraight = tmpStraight
        }
      }
    }
    //倒序算
    for(var z = new_arr.length - 1;z >= 5;z--){
      // console.log("==================z========================= : "+z)
      var numList = {}
      for(var i in list){
        numList[i] = list[i]
      }
      var tmpStraight = []
      //指定位置开始获取
      var arrResult = this.getContinuousArray(new_arr.slice(z,new_arr.length))
      // console.log("arrResult11")
      // console.log(arrResult)
      //获取其中长度大于5的取出
      for(var i = 0;i < arrResult.length;i++){
        if(arrResult[i].length >= 5){
          tmpStraight.push(arrResult[i])
          for(var j = 0;j < arrResult[i].length;j++){
            numList[arrResult[i][j]]--
          }
        }
      }
      var numArr = []
      for(var i in numList){
        if(numList[i] > 0){
          numArr.push(parseInt(i))
        }
      }
      numArr.sort(function(a,b){return card_weight[a] - card_weight[b]})
      // console.log("numArr : ")
      // console.log(numArr)
      //所有数字再次获取
      arrResult = this.getContinuousArray(numArr.slice(0,numArr.length))
      // console.log("arrResult22")
      // console.log(arrResult)
      //获取其中长度大于5的取出
      for(var i = 0;i < arrResult.length;i++){
        if(arrResult[i].length >= 5){
          tmpStraight.push(arrResult[i])
          for(var j = 0;j < arrResult[i].length;j++){
            numList[arrResult[i][j]]--
          }
        }
      }
      // console.log("numList : ")
      // console.log(numList)
      var signCount = 0
      var allCount = 0
      for(var i in numList){
        if(numList[i] == 1){
          signCount++
        }
        allCount += numList[i]
      }
      if(minSign == false){
        minSign = signCount
        minAll = allCount
        bestStraight = tmpStraight
      }else{
        if(minSign > signCount || (minSign == signCount && allCount > minAll)){
          minSign = signCount
          minAll = allCount
          bestStraight = tmpStraight
        }
      }
    }
    // console.log("minSign : "+minSign)
    // console.log("minAll : "+minAll)
    // console.log(bestStraight)
    var result = {
      minSign : minSign,
      bestStraight : bestStraight
    }
    return result
  }
  /**
   * 获取连续数组分组
   * @Author   wfd
   * @DateTime 2018-05-15
   * @param    {[type]}   arr [数组]
   * @return   {[type]}       [分组]
   */
  this.getContinuousArray = function(arr) {
    if(!arr || !arr.length){
      return []
    }
    var result = []
    var i = 0
    result[i] = [arr[0]];
    arr.reduce(function(prev, cur){
      card_weight[cur]-card_weight[prev] === 1 ? result[i].push(cur) : result[++i] = [cur];
      return cur;
    });
    return result;
  }
  /**
   * 获取最优胜利牌组，使打出后剩余手牌最优
   * @Author   wfd
   * @DateTime 2018-05-14
   * @param    {[type]}   result   [当前打出牌型]
   * @param    {[type]}   handCard [手牌]
   * @return   {[type]}            [返回牌型，无则为false]
   */
  this.getBestWinCardList = function(result,handCard) {
    var handRest = 0
    for(var i = 0;i < handCard.length;i++){
      if(handCard[i].state){
        handRest++
      }
    }
    var maxValue = false
    var maxIndex = false
    var resultAll = this.getAllWinCardList(result,handCard)
    // console.log("======================11")
    // console.log(resultAll)
    // console.log("======================22")
    for(var i = 0;i < resultAll.length;i++){
      var tmpValue = this.getSurplusValue(resultAll[i],handCard,handRest)
      // console.log("tmpValue : "+tmpValue)
      if(maxIndex === false){
        maxValue = tmpValue
        maxIndex = i
      }else{
        if(maxValue < tmpValue){
          maxValue = tmpValue
          maxIndex = i
        }
      }
    }
    // console.log("maxIndex : "+maxIndex)
    // console.log("maxValue : "+maxValue)
    // console.log(resultAll[maxIndex])
    if(maxIndex !== false){
      return resultAll[maxIndex]
    }else{
      return []
    }
  }
  /**
   * 获取最优胜利牌组，使打出后剩余手牌最优，同时判断下一个玩家是否能赢
   * @Author   wfd
   * @DateTime 2018-05-14
   * @param    {[type]}   result   [当前打出牌型]
   * @param    {[type]}   handCard [手牌]
   * @return   {[type]}            [返回牌型，无则为false]
   */
  this.getRobotBestWinCardList = function(result,handCard,otherHandCard,ohterRest) {
    var handRest = 0
    for(var i = 0;i < handCard.length;i++){
      if(handCard[i].state){
        handRest++
      }
    }
    var maxValue = false
    var maxIndex = false
    var resultAll = this.getAllWinCardList(result,handCard)
    var arr2 = []
    for(var i = 0;i < resultAll.length;i++){
      var tmpResult = this.getCardType(resultAll[i])
      // console.log("resultAll[i]",resultAll[i],"tmpResult",tmpResult)
      var willPlayList = this.getAllWinCardList(tmpResult,otherHandCard)
      var flag = true
      for(var j = 0;j < willPlayList.length;j++){
        if(willPlayList[j].length == ohterRest){
          // console.log("111111111 : ",willPlayList[j])
          flag = false
          break
        }
      }
      if(flag){
        arr2.push(resultAll[i])
      }
    }
    if(arr2.length){
      resultAll = arr2
    }
    for(var i = 0;i < resultAll.length;i++){
      var tmpValue = this.getSurplusValue(resultAll[i],handCard,handRest)
      // console.log("tmpValue : "+tmpValue)
      if(maxIndex === false){
        maxValue = tmpValue
        maxIndex = i
      }else{
        if(maxValue < tmpValue){
          maxValue = tmpValue
          maxIndex = i
        }
      }
    }
    // console.log("maxIndex : "+maxIndex)
    // console.log("maxValue : "+maxValue)
    // console.log(resultAll[maxIndex])
    if(maxIndex !== false){
      return resultAll[maxIndex]
    }else{
      return []
    }
  }
  /**
   * 获取最小胜利牌组
   * @Author   wfd
   * @DateTime 2018-05-14
   * @param    {[type]}   result   [当前打出牌型]
   * @param    {[type]}   handCard [手牌]
   * @return   {[type]}            [返回牌型，无则为false]
   */
  this.getMinWinCardList = function(result,handCard) {
    var arr = this.getAllWinCardList(result,handCard)
    for(var i = 0;i < arr.length - 1;i++){
      for(var j = i + 1; j < arr.length;j++){
        if(this.compareWithType(this.getCardType(arr[j],arr[j].length),this.getCardType(arr[i],arr[i].length))){
          var tmpCardList = arr[i]
          arr[i] = arr[j]
          arr[j] = tmpCardList
        }
      }
    }
    return arr
  }
  /**
   * 获取最大胜利牌组
   * @Author   wfd
   * @DateTime 2018-05-14
   * @param    {[type]}   result   [当前打出牌型]
   * @param    {[type]}   handCard [手牌]
   * @return   {[type]}            [返回牌型，无则为false]
   */
  this.getMaxWinCardList = function(result,handCard) {
    var arr = this.getAllWinCardList(result,handCard)
    for(var i = 0;i < arr.length - 1;i++){
      for(var j = i + 1; j < arr.length;j++){
        if(this.compareWithType(this.getCardType(arr[i],arr[i].length),this.getCardType(arr[j],arr[j].length))){
          var tmpCardList = arr[i]
          arr[i] = arr[j]
          arr[j] = tmpCardList
        }
      }
    }
    return arr
  }
  /**
   * 获取所有可胜利牌组列表
   * @Author   wfd
   * @DateTime 2018-05-14
   * @param    {[type]}   result   [当前打出牌型]
   * @param    {[type]}   handCard [手牌
   * ]
   * @return   {[type]}            [返回牌型，无则为空数组[]]
   */
  this.getAllWinCardList = function(result,handCard) {
    // console.log(result)
    //剩余卡组
    var cardList = []
    //点数剩余数量
    var numList = {}
    //返回数组
    var new_arr = []

    for(var i = 0;i < handCard.length;i++){
      if(handCard[i].state){
        cardList.push(handCard[i])
        if(!numList[handCard[i].num]){
          numList[handCard[i].num] = 0
        }
        numList[handCard[i].num]++
      }
    }
    //排序
    for(var i = 0;i < cardList.length - 1;i++){
      for(var j = i + 1;j < cardList.length;j++){
        if(card_weight[cardList[j].num] > card_weight[cardList[i].num] || (cardList[j].num == cardList[i].num && cardList[j].type > cardList[i].type)){
          var tmp = cardList[j]
          cardList[j] = cardList[i]
          cardList[i] = tmp
        }
      }
    }
    // console.log(cardList)
    if(cardList.length >= result.cardList.length){
      // console.log("result.type",result.type)
      //根据不同类型获取
      switch(result.type){
        case CARD_TYPE_SIGN :
          //单牌
          for(var i = 0;i < cardList.length;i++){
            if(card_weight[cardList[i].num] > card_weight[result.maxCard.num]){
              new_arr.push([cardList[i]])
            }
          }
        break
        case CARD_TYPE_PAIRS:
          //对子
          for(var i in numList){
            if(card_weight[parseInt(i)] > card_weight[result.maxCard.num]){
              var tmpArea = this.getCardIndex(cardList,i,2)
              if(tmpArea){
                new_arr.push(tmpArea)
              }
            }
          }
        break
        case CARD_TYPE_EVENFOR_PAIRS:
          //连对  最大为A时不判断
          if(result.maxCard.num == 1){
            break
          }
          var pairsLength = result.cardList.length / 2
          for(var i = result.maxCard.num - pairsLength + 1; i <= 14 - pairsLength;i++){
            var flag = true
            for(var j = i + 1;j <= i + pairsLength;j++){
              var index = j
              if(j == 14){
                index = 1
              }
              if(!(numList[index] && numList[index] >= 2)){
                flag = false
                break
              }
            }
            if(flag){
              var tmpArea = []
              for(var j = i + 1;j <= i + pairsLength;j++){
                var index = j
                if(j == 14){
                  index = 1
                }
                tmpArea = tmpArea.concat(this.getCardIndex(cardList,index,2))
              }
              new_arr.push(tmpArea)
            }
          }
        break
        case CARD_TYPE_STRAIGHT:
          //顺子  最大为A时不判断
          if(result.maxCard.num == 1){
            break
          }
          var straightLength = result.cardList.length
          for(var i = result.maxCard.num - straightLength + 1; i <= 14 - straightLength;i++){
            var flag = true
            for(var j = i + 1;j <= i + straightLength;j++){
              var index = j
              if(j == 14){
                index = 1
              }
              if(!(numList[index] && numList[index] >= 1)){
                flag = false
                break
              }
            }
            if(flag){
              var tmpArea = []
              for(var j = i + 1;j <= i + straightLength;j++){
                var index = j
                if(j == 14){
                  index = 1
                }
                tmpArea = tmpArea.concat(this.getCardIndex(cardList,index,1))
              }
              new_arr.push(tmpArea)
            }
          }
        break
        case CARD_TYPE_THREE_WITH_TWO:
          if(cardList.length < 5){
            break
          }
          //三带二
          for(var i in numList){
            if(numList[i] == 3 && card_weight[parseInt(i)] > card_weight[result.maxCard.num]){
              var tmpArea = this.getCardIndex(cardList,i,3)
              var count = 0
              //从小到大找两张单牌
              for(var j = cardList.length - 1;j >= 0;j--){
                if(numList[cardList[j].num] == 1){
                  tmpArea = tmpArea.concat(this.getCardIndex(cardList,cardList[j].num,1))
                  count++
                }else if(numList[cardList[j].num] == 2){
                  if(2 - count == 1){
                    tmpArea = tmpArea.concat(this.getCardIndex(cardList,cardList[j].num,1))
                    count++
                  }else if(2 - count >= 2){
                    tmpArea = tmpArea.concat(this.getCardIndex(cardList,cardList[j].num,2))
                    count += 2
                  }
                }else{
                  if(cardList[j].num != i){
                    tmpArea.push(cardList[j])
                    count++
                  }
                }
                if(count == 2){
                  new_arr.push(tmpArea)
                  break
                }
              }
            }
          }
        break
        case CARD_TYPE_SANSHUN:
          //三顺
          if(result.maxCard.num == 1){
            break
          }
          var length = result.cardList.length / 3
          for(var i = result.maxCard.num - length + 1; i <= 14 - length;i++){
            var flag = true
            for(var j = i + 1;j <= i + length;j++){
              var index = j
              if(j == 14){
                index = 1
              }
              if(!numList[index] || numList[index] < 3){
                flag = false
                break
              }
            }
            if(flag){
              var tmpArea = []
              for(var j = i + 1;j <= i + length;j++){
                var index = j
                if(j == 14){
                  index = 1
                }
                // console.log(i,j,numList[i],numList[j])
                tmpArea = tmpArea.concat(this.getCardIndex(cardList,index,3))
              }
              new_arr.push(tmpArea)
            }
          }
        break
        case CARD_TYPE_PLANE:
          //飞机  最大为A时不判断
          if(result.maxCard.num == 1){
            break
          }
          var planeLength = result.cardList.length / 5
          // console.log("planeLength : ",planeLength)
          for(var i = result.maxCard.num - planeLength + 1; i <= 14 - planeLength;i++){
            var flag = true
            for(var j = i + 1;j <= i + planeLength;j++){
              var index = j
              if(j == 14){
                index = 1
              }
              if(!(numList[index] && numList[index] >= 3)){
                flag = false
                break
              }
            }
            if(flag){
              var tmpArea = []
              for(var j = i + 1;j <= i + planeLength;j++){
                var index = j
                if(j == 14){
                  index = 1
                }
                tmpArea = tmpArea.concat(this.getCardIndex(cardList,index,3))
              }
              // console.log(tmpArea)
              var count = 0
              //从小到大找planeLength * 2张单牌
              for(var j = cardList.length - 1;j >= 0;j--){
                if(numList[cardList[j].num] == 1){
                  if(j == cardList.length - 1 || cardList[j].num != cardList[j + 1].num){
                    tmpArea = tmpArea.concat(this.getCardIndex(cardList,cardList[j].num,1))
                    count++
                  }
                }else if(numList[cardList[j].num] == 2){
                  if(j == cardList.length - 1 || cardList[j].num != cardList[j + 1].num){
                    if(planeLength * 2 - count == 1){
                      tmpArea = tmpArea.concat(this.getCardIndex(cardList,cardList[j].num,1))
                      count++
                    }else if(planeLength * 2 - count >= 2){
                      tmpArea = tmpArea.concat(this.getCardIndex(cardList,cardList[j].num,2))
                      count += 2
                    }
                  }
                }else{
                    if(cardList[j].num > i + planeLength || cardList[j].num < i + 1){
                      var flag = true
                      for(var z in tmpArea){
                        if(tmpArea[z].num == cardList[j].num && tmpArea[z].type == cardList[j].type){
                          flag = false
                          break
                        }
                      }
                      if(flag){
                        tmpArea.push(cardList[j])
                        count++
                      }
                    }
                  }
                if(count == planeLength * 2 &&tmpArea.length === result.cardList.length){
                  new_arr.push(tmpArea)
                  break
                }
              }
            }
          }
        break
        case CARD_TYPE_FOUR_WITH_THREE:
          //四带三
          for(var i in numList){
            if(numList[i] == 4 && card_weight[parseInt(i)] > card_weight[result.maxCard.num]){
              var tmpArea = this.getCardIndex(cardList,i,4)
              var count = 0
              //从小到大找三张单牌
              for(var j = 0;j < cardList.length;j++){
                if(numList[cardList[j].num] == 1){
                  tmpArea = tmpArea.concat(this.getCardIndex(cardList,cardList[j].num,1))
                  count++
                }else if(numList[cardList[j].num] == 2){
                  if(3 - count == 1){
                    tmpArea = tmpArea.concat(this.getCardIndex(cardList,cardList[j].num,1))
                    count++
                  }else if(3 - count >= 2){
                    tmpArea = tmpArea.concat(this.getCardIndex(cardList,cardList[j].num,2))
                    count += 2
                  }
                }
                if(count == 3){
                  new_arr.push(tmpArea)
                  break
                }
              }
            }
          }
        break
      }
    }
    //判断炸弹
    if(result.type == CARD_TYPE_BOMB){
      for(var i in numList){
        if(numList[i] == 4 && card_weight[parseInt(i)] > card_weight[result.maxCard.num]){
          var tmpArea = this.getCardIndex(cardList,i,4)
          new_arr.push(tmpArea)
        }
      }
    }else{
      //炸弹
      for(var i in numList){
        if(numList[i] == 4){
          var tmpArea = this.getCardIndex(cardList,i,4)
          new_arr.push(tmpArea)
        }
      }
    }
    return new_arr
  }
  /**
   * 获取牌下标
   * @Author   wfd
   * @DateTime 2018-05-16
   * @param    {[type]}   cardList [牌列表]
   * @param    {[type]}   num      [数字]
   * @param    {[type]}   count    [数量]
   * @return   {[type]}            [下标列表]
   */
  this.getCardIndex = function(cardList,num,count) {
    var curCount = 0
    var tmpArea = []
    for(var i = 0;i < cardList.length;i++){
      if(cardList[i].num == num){
        tmpArea.push(cardList[i])
        curCount++
        if(curCount == count){
          return tmpArea
        }
      }
    }
    return false
  }
  /**
   * 获取牌组价值
   * @Author   wfd
   * @DateTime 2018-05-17
   * @param    cardList   [牌组]
   * @param    handRest   [剩余手牌]
   * @return   {[type]}            []
   */
  this.getCardListValue = function(cardList,handRest) {
    var value = 0
    for(var i in cardList){
      value += card_weight[cardList[i].num]
    }
    var result = this.getCardType(cardList,handRest)
    switch(result.type){
      case CARD_TYPE_SIGN:
        if(card_weight[result.maxCard.num] >= 14){
          value += card_weight[result.maxCard.num] * 0.5
        }else if(card_weight[result.maxCard.num] <= 7){
          value -= card_weight[result.maxCard.num] * 0.5
        }
      break
      case CARD_TYPE_PAIRS:
        if(card_weight[result.maxCard.num] >= 13){
          value += card_weight[result.maxCard.num]
        }else if(card_weight[result.maxCard.num] <= 6){
          value -= card_weight[result.maxCard.num]
        }else{
          value += card_weight[result.maxCard.num] * 0.5
        }
      break
      case CARD_TYPE_EVENFOR_PAIRS:
        value += 2 * result.cardList.length + card_weight[result.maxCard.num] * 3
      break
      case CARD_TYPE_STRAIGHT:
        value += 2 * result.cardList.length + card_weight[result.maxCard.num] * 2
      break
      case CARD_TYPE_THREE:
        value += 15 + card_weight[result.maxCard.num] * 2
      break
      case CARD_TYPE_THREE_WITH_ONE:
         value += 15 + card_weight[result.maxCard.num] * 2
      break
      case CARD_TYPE_THREE_WITH_TWO:
         value += 15 + card_weight[result.maxCard.num] * 2
      break
      case CARD_TYPE_PLANE:
         value += 3 * result.cardList.length + card_weight[result.maxCard.num] * 2
      break
      case CARD_TYPE_BOMB:
         value += 40 + card_weight[result.maxCard.num] * 2
      break
      case CARD_TYPE_FOUR_WITH_THREE:
         value += 30
      break
      case CARD_TYPE_SANSHUN:
        value += 3 * result.cardList.length + card_weight[result.maxCard.num] * 2
      break
    }
    return value
  }
  /**
   * 获取手牌价值
   * @Author   wfd
   * @DateTime 2018-05-17
   * @param    {[type]}   hand [description]
   * @return   {[type]}        [description]
   */
  this.getHandCardValue = function(hand,handRest) {
    var result = this.getBestSubarea(hand,handRest)
    var value = 0
    for(var i = 0;i < result.length;i++){
      value += this.getCardListValue(result[i],handRest)
    }
    value -= result.length * 3
    return value
  }
  /**
   * 获取手牌打出后剩余价值
   * @Author   wfd
   * @DateTime 2018-05-17
   * @param    {[type]}   cardList [description]
   * @param    {[type]}   handCard [description]
   * @param    {[type]}   handRest [description]
   * @return   {[type]}            [description]
   */
  this.getSurplusValue = function(cardList,handCard,handRest) {
    var curCardList = []
    for(var i = 0;i < handCard.length;i++){
      curCardList.push(this.deepCopy(handCard[i]))
    }
    for(var i = 0;i < cardList.length;i++){
      for(var j = 0;j < curCardList.length;j++){
        if(curCardList[j].index == cardList[i].index){
          curCardList[j].state = false
        }
      }
    }
    // console.log(handCard)
    // console.log(curCardList)
    var curHandRest = handRest - cardList.length
    var allResult = this.getBestSubarea(curCardList,curHandRest)
    var value = 0
    for(var i = 0;i < allResult.length;i++){
      var tmpValue = this.getCardListValue(allResult[i],curHandRest)
      value += tmpValue
    }
    return value
  }
  /**
   * 获取最低价值牌组
   * @Author   wfd
   * @DateTime 2018-05-17
   * @param    {[type]}   handCard [description]
   * @param    {[type]}   handRest [description]
   * @return   {[type]}            [description]
   */
  this.getLowValueCard = function(handCard,handRest) {
    var arr = this.getBestSubarea(handCard)
    // console.log(arr)
    if(arr.length <= 1){
      return arr[0]
    }else{
      var minValue = false
      var minIndex = false
      for(var i = 0;i < arr.length;i++){
        var tmpValue = this.getCardListValue(arr[i],handRest)
        tmpValue = tmpValue / arr[i].length - arr[i].length * 3
        // console.log("i : "+tmpValue)
        if(minIndex === false){
          minValue = tmpValue
          minIndex = i
        }else if(minValue > tmpValue){
          minValue = tmpValue
          minIndex = i
        }
      }
      // console.log("minValue : "+minValue)
      // console.log("minIndex : "+minIndex)
      return arr[minIndex]
    }
  }
  /**
   * 获取最低价值牌组，但不会使下家打完
   * @Author   wfd
   * @DateTime 2018-05-17
   * @param    {[type]}   handCard [description]
   * @param    {[type]}   handRest [description]
   * @return   {[type]}            [description]
   */
  this.getRobotLowValueCard = function(handCard,handRest,otherHandCard,ohterRest) {
    var arr = this.getBestSubarea(handCard)
    var arr2 = []
    for(var i = 0;i < arr.length;i++){
      var tmpResult = this.getCardType(arr[i])
      // console.log("arr[i]",arr[i],"tmpResult",tmpResult)
      var willPlayList = this.getAllWinCardList(tmpResult,otherHandCard)
      var flag = true
      for(var j = 0;j < willPlayList.length;j++){
        if(willPlayList[j].length == ohterRest){
          // console.log("111111111 : ",willPlayList[j])
          flag = false
          break
        }
      }
      if(flag){
        arr2.push(arr[i])
      }
    }
    if(arr2.length){
      arr = arr2
      if(arr.length <= 1){
        return arr[0]
      }else{
        var minValue = false
        var minIndex = false
        for(var i = 0;i < arr.length;i++){
          var tmpValue = this.getCardListValue(arr[i],handRest)
          tmpValue = tmpValue / arr[i].length - arr[i].length * 3
          // console.log("i : "+tmpValue)
          if(minIndex === false){
            minValue = tmpValue
            minIndex = i
          }else if(minValue > tmpValue){
            minValue = tmpValue
            minIndex = i
          }
        }
        // console.log("minValue : "+minValue)
        // console.log("minIndex : "+minIndex)
        return arr[minIndex]
      }
    }else{
      //从高到低打
      if(arr.length <= 1){
        return arr[0]
      }else{
        var maxValue = false
        var maxIndex = false
        for(var i = 0;i < arr.length;i++){
          var tmpValue = this.getCardListValue(arr[i],handRest)
          tmpValue = tmpValue / arr[i].length - arr[i].length * 3
          // console.log("i : "+tmpValue)
          if(maxIndex === false){
            maxValue = tmpValue
            maxIndex = i
          }else if(maxValue < tmpValue){
            maxValue = tmpValue
            maxIndex = i
          }
        }
        // console.log("minValue : "+minValue)
        // console.log("minIndex : "+minIndex)
        return arr[maxIndex]
      }
    }
  }
  /**
   * 深度copy
   * @Author   wfd
   * @DateTime 2018-05-17
   * @param    {[type]}   source [description]
   * @return   {[type]}          [description]
   */
  this.deepCopy = function(source) {
    var result={}
    for (var key in source) {
          result[key] = typeof source[key]==="object"? deepCopy(source[key]): source[key]
       } 
    return result;
  }
}